using System.Text.Json.Serialization;

namespace Sage.CloudStorage.Qiniu.Models
{
    /// <summary>
    /// 完成分片上传请求类
    /// 包含完成整个分片上传任务所需的所有信息
    /// </summary>
    /// <remarks>
    /// **请求用途**：
    /// - 通知七牛云所有分片已上传完毕
    /// - 提供分片清单用于文件合并
    /// - 设置最终文件的元数据信息
    /// - 触发文件合成和后续处理
    /// 
    /// **工作流程**：
    /// 1. 客户端收集所有已上传分片的信息
    /// 2. 构建CompleteMultipartUploadRequest对象
    /// 3. 发送请求到七牛云完成上传API
    /// 4. 七牛云验证分片并合成最终文件
    /// 5. 返回最终文件的信息和访问地址
    /// 
    /// **重要提醒**：
    /// - 分片列表必须完整，缺少任何分片都会失败
    /// - 分片必须按PartNumber升序排列
    /// - 所有ETag必须准确无误
    /// - 请求发送后不能修改或撤销
    /// </remarks>
    public class CompleteMultipartUploadRequest
    {
        /// <summary>
        /// 已经上传的分片列表
        /// 包含分片号(PartNumber)和分片标识(ETag)的完整清单
        /// </summary>
        /// <remarks>
        /// **分片列表要求**：
        /// - **完整性**：必须包含所有已上传的分片
        /// - **顺序性**：必须按PartNumber升序排列
        /// - **准确性**：每个分片的ETag必须准确
        /// - **连续性**：分片号必须连续，从1开始
        /// - **唯一性**：每个分片号只能出现一次
        /// 
        /// **验证机制**：
        /// - 七牛云会逐一验证每个分片的有效性
        /// - 检查分片号的连续性和完整性
        /// - 验证ETag与实际上传分片的一致性
        /// - 确保分片大小符合要求（除最后一个分片外≥1MB）
        /// 
        /// **构建示例**：
        /// ```csharp
        /// var request = new CompleteMultipartUploadRequest
        /// {
        ///     Parts = new List&lt;CompletePartInfo&gt;
        ///     {
        ///         new() { PartNumber = 1, Etag = "FqvtxHpe3j-rEzkImMUWDsmvu27D" },
        ///         new() { PartNumber = 2, Etag = "FpLiADEaVq6Lt9B7tj4jKwMCC6Mb" },
        ///         new() { PartNumber = 3, Etag = "FnYXMvhIowjpnAZI_VmuBkT4vBSK" }
        ///     }
        /// };
        /// ```
        /// 
        /// **最佳实践**：
        /// - 在分片上传过程中实时维护分片列表
        /// - 上传成功后立即记录PartNumber和ETag
        /// - 提交前对分片列表进行完整性检查
        /// - 支持断点续传时持久化存储分片信息
        /// 
        /// **错误处理**：
        /// - 分片列表不完整：返回400错误
        /// - ETag不匹配：返回400错误
        /// - 分片号不连续：返回400错误
        /// - 分片大小不符合要求：返回400错误
        /// </remarks>
        [JsonPropertyName("parts")]
        public List<CompletePartInfo> Parts { get; set; } = [];

        /// <summary>
        /// 上传的原始文件名
        /// 用于设置最终文件的文件名信息，影响魔法变量的使用
        /// </summary>
        /// <remarks>
        /// **文件名用途**：
        /// - **魔法变量**：在上传策略的returnBody、callbackBody等中使用$(fname)
        /// - **扩展名提取**：支持$(ext)魔法变量获取文件扩展名
        /// - **后缀获取**：支持$(suffix)魔法变量获取文件后缀
        /// - **元数据设置**：作为文件的元数据信息保存
        /// 
        /// 🪄 **魔法变量示例**：
        /// 如果Fname设置为"document.pdf"，则：
        /// - $(fname) = "document.pdf"
        /// - $(ext) = ".pdf"
        /// - $(suffix) = "pdf"
        /// 
        /// **设置建议**：
        /// - 使用原始上传文件的完整文件名
        /// - 包含文件扩展名，便于类型识别
        /// - 避免包含特殊字符和非法字符
        /// - 长度适中，避免过长的文件名
        /// 
        /// **业务价值**：
        /// - 便于文件管理和识别
        /// - 支持下载时的文件名显示
        /// - 用于文件类型判断和处理
        /// - 提供更好的用户体验
        /// 
        /// **注意事项**：
        /// - 如果不设置，相关魔法变量将无法使用
        /// - 文件名应该与实际上传的文件匹配
        /// - 特殊字符可能影响URL生成和访问
        /// </remarks>
        [JsonPropertyName("fname")]
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        public string? Fname { get; set; }

        /// <summary>
        /// 文件的MIME类型
        /// 指定最终文件的内容类型，影响浏览器的处理方式
        /// </summary>
        /// <remarks>
        /// **MIME类型作用**：
        /// - **浏览器行为**：决定浏览器如何处理文件（下载、预览、播放等）
        /// - **内容识别**：帮助系统和应用程序识别文件类型
        /// - **安全防护**：正确的MIME类型有助于安全策略执行
        /// - **用户体验**：影响文件在浏览器中的显示和交互方式
        /// 
        /// **设置方式**：
        /// - **指定值**：如果设置了mimeType，七牛云使用指定的类型
        /// - **自动检测**：如果未设置，七牛云根据文件内容自动检测
        /// - **策略控制**：受上传策略中detectMime参数影响
        /// 
        /// **常用MIME类型**：
        /// - 图片：image/jpeg, image/png, image/gif, image/webp
        /// - 视频：video/mp4, video/avi, video/quicktime
        /// - 音频：audio/mpeg, audio/wav, audio/ogg
        /// - 文档：application/pdf, text/plain, application/json
        /// - 压缩：application/zip, application/x-rar-compressed
        /// 
        /// **设置示例**：
        /// ```csharp
        /// // 图片文件
        /// request.MimeType = "image/jpeg";
        /// 
        /// // 视频文件
        /// request.MimeType = "video/mp4";
        /// 
        /// // PDF文档
        /// request.MimeType = "application/pdf";
        /// 
        /// // 让七牛云自动检测
        /// request.MimeType = null; // 或不设置
        /// ```
        /// 
        /// **最佳实践**：
        /// - 根据实际文件类型设置正确的MIME类型
        /// - 不确定时可以让七牛云自动检测
        /// - 对于安全敏感的应用，建议明确指定
        /// - 与文件扩展名保持一致
        /// 
        /// **注意事项**：
        /// - 错误的MIME类型可能影响文件访问
        /// - 某些浏览器对MIME类型敏感
        /// - 自动检测可能不够准确，建议手动指定
        /// </remarks>
        [JsonPropertyName("mimeType")]
        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
        public string? MimeType { get; set; }
    }
}
